package summary;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 * @Author: 海琳琦
 * @Date: 2022/4/20 9:57
 * https://leetcode-cn.com/problems/network-delay-time/
 */
public class Title743 {

    /**
     * 迪杰斯特拉算法
     * @param times
     * @param n
     * @param k
     * @return
     */
    public static int networkDelayTime(int[][] times, int n, int k) {
        final int INF = Integer.MAX_VALUE / 2;
        //邻接矩阵
        int[][] matrix = new int[n][n];
        for (int i = 0; i < n; i++) {
            Arrays.fill(matrix[i], INF);
        }
        //邻接矩阵初始化
        for (int[] edge : times) {
            //邻接矩阵编号从0开始
            int x = edge[0] - 1;
            int y = edge[1] - 1;
            int len = edge[2];
            matrix[x][y] = len;
        }
        //从原点到某点的距离数组
        int[] distance = new int[n];
        Arrays.fill(distance, INF);
        //从k开始，原点到原点的距离初始化为0
        distance[k - 1] = 0;

        //确定从原点到各个节点是否被确定距离
        boolean[] used = new boolean[n];

        //记录路径的前驱
        int[] prePath = new int[n];
        Arrays.fill(prePath, INF);
        for (int i = 0; i < n; i++) {
            //从还未确定最短路径的点中，寻找最小距离
            int x = -1;
            for (int j = 0; j < n; j++) {
                if (!used[j] && (x == -1 || distance[j] < distance[x])) {
                    x = j;
                }
            }
            //用该点更新其他所有点的距离
            used[x] = true;
            for (int j = 0; j < n; j++) {
                if (!used[j] && distance[x] + matrix[x][j] < distance[j]) {
                    distance[j] = distance[x] + matrix[x][j];
                    prePath[j] = x;
                }
            }
        }
        int max = 0;
        for (int i = 0; i < distance.length; i++) {
            if (distance[i] > max) {
                max = distance[i];
            }
        }
        //记录下从原点到各点的路径
        List<List<Integer>> result = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            LinkedList<Integer> temp = new LinkedList<>();
            if (prePath[i] != INF) {
                int path = i;
                while (path != k - 1) {
                    temp.addFirst(path);
                    path = prePath[path];
                }
                temp.addFirst(k - 1);
            }else{
                temp.add(-1);
            }
            result.add(temp);
        }
        return max == INF ? -1 : max;
    }

    public static int networkDelayTime1(int[][] times, int n, int k) {
        final int INF = Integer.MAX_VALUE / 2;
        //迪杰斯特拉算法
        //邻接矩阵
        int[][] matrix = new int[n][n];
        //初始化邻接矩阵
        for (int i = 0; i < n; i++) {
            Arrays.fill(matrix[i], INF);
        }
        for (int i = 0; i < times.length; i++) {
            int x = times[i][0] - 1;
            int y = times[i][1] - 1;
            int len = times[i][2];
            matrix[x][y] = len;
        }
        //存放原点到各个点的最短距离
        int[] distance = new int[n];
        Arrays.fill(distance, INF);
        distance[k - 1] = 0;
        //判断该点是否已经确定最短距离
        boolean[] used = new boolean[n];
        //获得路径的前缀
        int[] path = new int[n];
        Arrays.fill(path, -1);
        for (int i = 0; i < n; i++) {
            int x = -1;
            for (int j = 0; j < n; j++) {
                if (!used[j] && (x == -1 || distance[j] < distance[x])) {
                    x = j;
                }
            }
            used[x] = true;
            for (int j = 0; j < n; j++) {
                if (!used[j] && (distance[x] + matrix[x][j] < distance[j])) {
                    distance[j] = distance[x] + matrix[x][j];
                    path[j] = x;
                }
            }
        }
        int max = 0;
        for (int i = 0; i < n; i++) {
            if (distance[i] > max) {
                max = distance[i];
            }
        }
        return max == INF ? -1 : max;
    }

    public static void main(String[] args) {
        int[][] graph = {{2,1,1},{2,3,1},{3,4,1}};
        int n = 4, k = 2;
        networkDelayTime(graph, n, k);
    }
}
